<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>2_react生命周期(旧)</title>
  </head>
  <body>
    <!-- 准备好一个容器 -->
    <div id="root"></div>
    <div id="root1"></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <!-- 引入react-dom 用于支持react操作dom -->
    <script
      type="text/javascript"
      src="../js/react-dom.development.js"
    ></script>
    <!-- 引入babel 将js转换成jsx -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <!-- type="text/babel" 表示写的是 jsx 使用babel 翻译 -->
    <script type="text/babel">
        /*
            初始化阶段：由ReactD0M.render()触发---初次渲染
                1.constructor()
                2.componentwillMount()
                3.render()
                4.componentDidMount() ===> 常用 初始化时做的事 例如开启定时器或者请求 或者 订阅消息
            2.更新阶段：由组件内部this.setsate()或父组件重新render触发
                1.shouldComponentUpdate()
                2.componentwillUpdate()
                3.render()
                componentDidUpdate()
            3.卸载组件：由ReactDOM.unmountComponentAtNode()触发
                1.componentwillUnmount() ===> 常用 一般在钩子中 关闭定时器 取消订阅消息等
        */


      class Life extends React.Component {
        // 1. 构造函数
        constructor(props) {
          super(props);
          console.log("1. Life---constructor");
          this.state = { sum: 1 };
        }
        // 2. 组件即将挂载完毕
        componentWillMount() {
          console.log("2. Life---componentWillMount");
        }

        // 4. 组件挂载完毕
        componentDidMount() {
          console.log("4. Life---componentDidMount");
        }
        // 5. 组件即将被卸载时候调用
        componentWillUnmount() {
          console.log("5. Life---componentWillUnmount");
        }
        // 3. 组件渲染dom元素
        render() {
          console.log("3. Life---render");
          return (
            <div>
              <h2>sum: {this.state.sum}</h2>
              <button onClick={this.add}>点我++</button>
              <button onClick={this.death}>点我卸载组件</button>
              <button onClick={this.force}>强制更新</button>
            </div>
          );
        }

        // 1. 更新流程  当调用setState()时触发 如果返回true 则修改数据渲染页面 否则反之
        shouldComponentUpdate() {
          // return false
          console.log("1. Life---shouldComponentUpdate");
          return true;
        }
        // 2 .即将更新数据 然后会调用 render  (forceUpdate() 强制更新会直接跳过上面的 shouldComponentUpdate 这个流程 从componentWillUpdate直接往下走)
        componentWillUpdate() {
          console.log("2. Life---componentWillUpdate");
        }

        // 4. 数据完成更新
        componentDidUpdate() {
          console.log("4. Life---componentDidUpdate");
        }

        add = () => {
          this.setState({ sum: this.state.sum + 1 });
        };
        death = () => {
          ReactDOM.unmountComponentAtNode(document.getElementById("root"));
        };
        force = () => {
          // 强制更新
          this.forceUpdate();
        };
      }

    //   ReactDOM.render(<Life />, document.getElementById("root"));

      // 关于父子组件生命周期
      class A extends React.Component {
        changeCarName = ()=>{
            this.setState({carName:"宝马"})
        }
        render() {
          console.log("3. A---render");
          return (
            <div>
              <h1> A </h1>
              <button onClick={this.changeCarName}>点击我修改车型</button>
              <B carName={this.state.carName}/>
            </div>
          );
        }
        // 1. 构造函数
        constructor(props) {
          super(props);
          console.log("1. A---constructor");
          this.state = {carName:"奔驰"}
        }
        // 2. 组件即将挂载完毕
        componentWillMount() {
          console.log("2. A---componentWillMount");
        }

        // 4. 组件挂载完毕
        componentDidMount() {
          console.log("4. A---componentDidMount");
        }
        // 5. 组件即将被卸载时候调用
        componentWillUnmount() {
          console.log("5. A---componentWillUnmount");
        }
        // 1. 更新流程  当调用setState()时触发 如果返回true 则修改数据渲染页面 否则反之
        shouldComponentUpdate() {
          // return false
          console.log("1. A---shouldComponentUpdate");
          return true;
        }
        // 2 .即将更新数据 然后会调用 render  (forceUpdate() 强制更新会直接跳过上面的 shouldComponentUpdate 这个流程 从componentWillUpdate直接往下走)
        componentWillUpdate() {
          console.log("2. A---componentWillUpdate");
        }

        // 4. 数据完成更新
        componentDidUpdate() {
          console.log("4. A---componentDidUpdate");
        }


        // 父组件render 后 调用次方法 然后轮到 shouldComponentUpdate 注意:第一次渲染时候不调用 之后修改才调用
        componentWillReceiveProps(){
            console.log("0. A---componentWillReceiveProps");
        }

      }
      class B extends React.Component {
        // 1. 构造函数
        constructor(props) {
          super(props);
          console.log("1. B---constructor");
        }
        // 2. 组件即将挂载完毕
        componentWillMount() {
          console.log("2. B---componentWillMount");
        }

        // 4. 组件挂载完毕
        componentDidMount() {
          console.log("4. B---componentDidMount");
        }
        // 5. 组件即将被卸载时候调用
        componentWillUnmount() {
          console.log("5. B---componentWillUnmount");
        }
        // 1. 更新流程  当调用setState()时触发 如果返回true 则修改数据渲染页面 否则反之
        shouldComponentUpdate() {
          // return false
          console.log("1. B---shouldComponentUpdate");
          return true;
        }
        // 2 .即将更新数据 然后会调用 render  (forceUpdate() 强制更新会直接跳过上面的 shouldComponentUpdate 这个流程 从componentWillUpdate直接往下走)
        componentWillUpdate() {
          console.log("2. B---componentWillUpdate");
        }

        // 4. 数据完成更新
        componentDidUpdate() {
          console.log("4. B---componentDidUpdate");
        }
        // 父组件render 后 调用次方法 然后轮到 shouldComponentUpdate 注意:第一次渲染时候不调用 之后修改才调用
        componentWillReceiveProps(){
            console.log("0. B---componentWillReceiveProps");
        }
        render() {
          console.log("3. B---render");
          return (
            <div>
              <h1> B </h1>
              <h2>收到的车型是: {this.props.carName}</h2>
            </div>
          );
        }
      }
      ReactDOM.render(<A />, document.getElementById("root1"));
    </script>
  </body>
</html>
